home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 21 / AACD 21.iso / AACD / Utilities / Ghostscript / src / gspcolor.c < prev    next >
Encoding:
C/C++ Source or Header  |  2001-01-01  |  9.7 KB  |  320 lines

  1. /* Copyright (C) 1993, 2000 Aladdin Enterprises.  All rights reserved.
  2.   
  3.   This file is part of AFPL Ghostscript.
  4.   
  5.   AFPL Ghostscript is distributed with NO WARRANTY OF ANY KIND.  No author or
  6.   distributor accepts any responsibility for the consequences of using it, or
  7.   for whether it serves any particular purpose or works at all, unless he or
  8.   she says so in writing.  Refer to the Aladdin Free Public License (the
  9.   "License") for full details.
  10.   
  11.   Every copy of AFPL Ghostscript must include a copy of the License, normally
  12.   in a plain ASCII text file named PUBLIC.  The License grants you the right
  13.   to copy, modify and redistribute AFPL Ghostscript, but only under certain
  14.   conditions described in the License.  Among other things, the License
  15.   requires that the copyright notice and this notice be preserved on all
  16.   copies.
  17. */
  18.  
  19. /*$Id: gspcolor.c,v 1.4 2000/09/19 19:00:31 lpd Exp $ */
  20. /* Pattern color operators and procedures for Ghostscript library */
  21. #include "math_.h"
  22. #include "gx.h"
  23. #include "gserrors.h"
  24. #include "gsrop.h"
  25. #include "gsstruct.h"
  26. #include "gsutil.h"        /* for gs_next_ids */
  27. #include "gxarith.h"
  28. #include "gxfixed.h"
  29. #include "gxmatrix.h"
  30. #include "gxcoord.h"        /* for gs_concat, gx_tr'_to_fixed */
  31. #include "gxcspace.h"        /* for gscolor2.h */
  32. #include "gxcolor2.h"
  33. #include "gxdcolor.h"
  34. #include "gxdevice.h"
  35. #include "gxdevmem.h"
  36. #include "gxclip2.h"
  37. #include "gspath.h"
  38. #include "gxpath.h"
  39. #include "gxpcolor.h"
  40. #include "gzstate.h"
  41. #include "gsimage.h"
  42. #include "gsiparm4.h"
  43.  
  44. /* GC descriptors */
  45. public_st_pattern_template();
  46. public_st_pattern_instance();
  47.  
  48. /* Define the Pattern color space. */
  49. gs_private_st_composite(st_color_space_Pattern, gs_paint_color_space,
  50.      "gs_color_space_Pattern", cs_Pattern_enum_ptrs, cs_Pattern_reloc_ptrs);
  51. private cs_proc_num_components(gx_num_components_Pattern);
  52. private cs_proc_base_space(gx_base_space_Pattern);
  53. private cs_proc_remap_color(gx_remap_Pattern);
  54. private cs_proc_init_color(gx_init_Pattern);
  55. private cs_proc_restrict_color(gx_restrict_Pattern);
  56. private cs_proc_install_cspace(gx_install_Pattern);
  57. private cs_proc_adjust_cspace_count(gx_adjust_cspace_Pattern);
  58. private cs_proc_adjust_color_count(gx_adjust_color_Pattern);
  59. const gs_color_space_type gs_color_space_type_Pattern = {
  60.     gs_color_space_index_Pattern, false, false,
  61.     &st_color_space_Pattern, gx_num_components_Pattern,
  62.     gx_base_space_Pattern, gx_cspace_not_equal,
  63.     gx_init_Pattern, gx_restrict_Pattern,
  64.     gx_no_concrete_space,
  65.     gx_no_concretize_color, NULL,
  66.     gx_remap_Pattern, gx_install_Pattern,
  67.     gx_adjust_cspace_Pattern, gx_adjust_color_Pattern
  68. };
  69.  
  70. /* Initialize a generic pattern template. */
  71. void
  72. gs_pattern_common_init(gs_pattern_template_t * ppat,
  73.                const gs_pattern_type_t *type)
  74. {
  75.     ppat->type = type;
  76.     ppat->PatternType = type->PatternType;
  77.     uid_set_invalid(&ppat->uid);
  78.     ppat->client_data = 0;    /* for GC */
  79. }
  80.  
  81. /* Generic makepattern */
  82. int
  83. gs_make_pattern(gs_client_color * pcc, const gs_pattern_template_t * pcp,
  84.         const gs_matrix * pmat, gs_state * pgs, gs_memory_t * mem)
  85. {
  86.     return pcp->type->procs.make_pattern(pcc, pcp, pmat, pgs, mem);
  87. }
  88.  
  89. /*
  90.  * Do the generic work for makepattern: allocate the instance and the
  91.  * saved graphics state, and fill in the common members.
  92.  */
  93. int
  94. gs_make_pattern_common(gs_client_color *pcc,
  95.                const gs_pattern_template_t *ptemp,
  96.                const gs_matrix *pmat, gs_state *pgs, gs_memory_t *mem,
  97.                gs_memory_type_ptr_t pstype)
  98. {
  99.     gs_pattern_instance_t *pinst;
  100.     gs_state *saved;
  101.  
  102.     if (mem == 0)
  103.     mem = gs_state_memory(pgs);
  104.     rc_alloc_struct_1(pinst, gs_pattern_instance_t, pstype, mem,
  105.               return_error(gs_error_VMerror),
  106.               "gs_make_pattern_common");
  107.     pinst->rc.free = rc_free_pattern_instance;
  108.     pinst->type = ptemp->type;
  109.     saved = gs_state_copy(pgs, mem);
  110.     if (saved == 0) {
  111.     gs_free_object(mem, pinst, "gs_make_pattern_common");
  112.     return_error(gs_error_VMerror);
  113.     }
  114.     gs_concat(saved, pmat);
  115.     gs_newpath(saved);
  116.     pinst->saved = saved;
  117.     pcc->pattern = pinst;
  118.     return 0;
  119. }
  120.  
  121. /* Free the saved gstate when freeing a Pattern instance. */
  122. void
  123. rc_free_pattern_instance(gs_memory_t * mem, void *pinst_void,
  124.              client_name_t cname)
  125. {
  126.     gs_pattern_instance_t *pinst = pinst_void;
  127.  
  128.     gs_state_free(pinst->saved);
  129.     rc_free_struct_only(mem, pinst_void, cname);
  130. }
  131.  
  132. /* setpattern */
  133. int
  134. gs_setpattern(gs_state * pgs, const gs_client_color * pcc)
  135. {
  136.     int code = gs_setpatternspace(pgs);
  137.  
  138.     if (code < 0)
  139.     return code;
  140.     return gs_setcolor(pgs, pcc);
  141. }
  142.  
  143. /* setpatternspace */
  144. /* This does all the work of setpattern except for the final setcolor. */
  145. int
  146. gs_setpatternspace(gs_state * pgs)
  147. {
  148.     int code = 0;
  149.  
  150.     if (pgs->in_cachedevice)
  151.     return_error(gs_error_undefined);
  152.     if (pgs->color_space->type->index != gs_color_space_index_Pattern) {
  153.     gs_color_space cs;
  154.  
  155.     gs_cspace_init(&cs, &gs_color_space_type_Pattern, NULL);
  156.     /**************** base_space SETTING IS WRONG ****************/
  157.     cs.params.pattern.base_space =
  158.         *(gs_paint_color_space *) pgs->color_space;
  159.     cs.params.pattern.has_base_space = true;
  160.     *pgs->color_space = cs;
  161.     /* Don't change orig_base_cspace_index. */
  162.     pgs->orig_cspace_index = gs_color_space_index_Pattern;
  163.     cs_full_init_color(pgs->ccolor, &cs);
  164.     gx_unset_dev_color(pgs);
  165.     }
  166.     return code;
  167. }
  168.  
  169. /*
  170.  * Adjust the reference count of a pattern. This is intended to support
  171.  * applications (such as PCL) which maintain client colors outside of the
  172.  * graphic state. Since the pattern instance structure is opaque to these
  173.  * applications, they need some way to release or retain the instances as
  174.  * needed.
  175.  */
  176. void
  177. gs_pattern_reference(gs_client_color * pcc, int delta)
  178. {
  179.     if (pcc->pattern != 0)
  180.         rc_adjust(pcc->pattern, delta, "gs_pattern_reference");
  181. }
  182.  
  183. /* getpattern */
  184. /* This is only intended for the benefit of pattern PaintProcs. */
  185. const gs_pattern_template_t *
  186. gs_get_pattern(const gs_client_color * pcc)
  187. {
  188.     const gs_pattern_instance_t *pinst = pcc->pattern;
  189.  
  190.     return (pinst == 0 ? 0 : pinst->type->procs.get_pattern(pinst));
  191. }
  192.  
  193. /*
  194.  * Get the number of components in a Pattern color.
  195.  * For backward compatibility, and to distinguish Pattern color spaces
  196.  * from all others, we negate the result.
  197.  */
  198. private int
  199. gx_num_components_Pattern(const gs_color_space * pcs)
  200. {
  201.     return
  202.     (pcs->params.pattern.has_base_space ?
  203.      -1 - cs_num_components((const gs_color_space *)
  204.                 &(pcs->params.pattern.base_space)) :
  205.      -1 /* Pattern dictionary only */ );
  206. }
  207.  
  208. /* Get the base space of a Pattern color space. */
  209. private const gs_color_space *
  210. gx_base_space_Pattern(const gs_color_space * pcs)
  211. {
  212.     return
  213.     (pcs->params.pattern.has_base_space ?
  214.      (const gs_color_space *)&(pcs->params.pattern.base_space) :
  215.      NULL);
  216. }
  217.  
  218. /* Remap a Pattern color. */
  219. private int
  220. gx_remap_Pattern(const gs_client_color * pc, const gs_color_space * pcs,
  221.          gx_device_color * pdc, const gs_imager_state * pis,
  222.          gx_device * dev, gs_color_select_t select)
  223. {
  224.     if (pc->pattern == 0) {
  225.     color_set_null_pattern(pdc);
  226.     return 0;
  227.     }
  228.     return
  229.     pc->pattern->type->procs.remap_color(pc, pcs, pdc, pis, dev, select);
  230. }
  231.  
  232. /* Initialize a Pattern color. */
  233. private void
  234. gx_init_Pattern(gs_client_color * pcc, const gs_color_space * pcs)
  235. {
  236.     if (pcs->params.pattern.has_base_space) {
  237.     const gs_color_space *pbcs =
  238.     (const gs_color_space *)&pcs->params.pattern.base_space;
  239.  
  240.     cs_init_color(pcc, pbcs);
  241.     }
  242.     /*pcc->pattern = 0; *//* cs_full_init_color handles this */
  243. }
  244.  
  245. /* Force a Pattern color into legal range. */
  246. /* Note that if the pattern is uncolored (PaintType = 2), */
  247. /* the color space must have a base space: we check this here only */
  248. /* to prevent accessing uninitialized data, but if there is no base space, */
  249. /* it is an error that we count on being detected elsewhere. */
  250. private void
  251. gx_restrict_Pattern(gs_client_color * pcc, const gs_color_space * pcs)
  252. {
  253.     /* We need a special check for the null pattern. */
  254.     if (pcc->pattern &&
  255.     pcc->pattern->type->procs.uses_base_space(gs_get_pattern(pcc)) &&
  256.     pcs->params.pattern.has_base_space
  257.     ) {
  258.     const gs_color_space *pbcs =
  259.         (const gs_color_space *)&pcs->params.pattern.base_space;
  260.  
  261.     (*pbcs->type->restrict_color) (pcc, pbcs);
  262.     }
  263. }
  264.  
  265. /* Install a Pattern color space. */
  266. private int
  267. gx_install_Pattern(const gs_color_space * pcs, gs_state * pgs)
  268. {
  269.     if (!pcs->params.pattern.has_base_space)
  270.     return 0;
  271.     return (*pcs->params.pattern.base_space.type->install_cspace)
  272.     ((const gs_color_space *) & pcs->params.pattern.base_space, pgs);
  273. }
  274.  
  275. /* Adjust the reference counts for Pattern color spaces or colors. */
  276. private void
  277. gx_adjust_cspace_Pattern(const gs_color_space * pcs, int delta)
  278. {
  279.     if (pcs->params.pattern.has_base_space)
  280.     (*pcs->params.pattern.base_space.type->adjust_cspace_count)
  281.         ((const gs_color_space *)&pcs->params.pattern.base_space, delta);
  282. }
  283.  
  284. private void
  285. gx_adjust_color_Pattern(const gs_client_color * pcc,
  286.             const gs_color_space * pcs, int delta)
  287. {
  288.     gs_pattern_instance_t *pinst = pcc->pattern;
  289.  
  290.     rc_adjust_only(pinst, delta, "gx_adjust_color_Pattern");
  291.     if (pcs && pcs->params.pattern.has_base_space)
  292.     (*pcs->params.pattern.base_space.type->adjust_color_count)
  293.         (pcc, (const gs_color_space *)&pcs->params.pattern.base_space,
  294.          delta);
  295. }
  296.  
  297. /* GC procedures */
  298.  
  299. private 
  300. ENUM_PTRS_BEGIN_PROC(cs_Pattern_enum_ptrs)
  301. {
  302.     EV_CONST gs_color_space *const pcs = vptr;
  303.  
  304.     if (!pcs->params.pattern.has_base_space)
  305.     return 0;
  306.     return ENUM_USING(*pcs->params.pattern.base_space.type->stype,
  307.               &pcs->params.pattern.base_space,
  308.               sizeof(pcs->params.pattern.base_space), index);
  309. }
  310. ENUM_PTRS_END_PROC
  311. private RELOC_PTRS_WITH(cs_Pattern_reloc_ptrs, gs_color_space *pcs)
  312. {
  313.     if (!pcs->params.pattern.has_base_space)
  314.     return;
  315.     RELOC_USING(*pcs->params.pattern.base_space.type->stype,
  316.         &pcs->params.pattern.base_space,
  317.         sizeof(gs_paint_color_space));
  318. }
  319. RELOC_PTRS_END
  320.